package com.sd365.permission.centre.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.sd365.common.core.annotation.stuffer.IdGenerator;
import com.sd365.common.core.common.aop.MyPageInfo;
import com.sd365.common.core.common.exception.BusinessException;
import com.sd365.common.core.context.BaseContextHolder;
import com.sd365.common.util.BeanException;
import com.sd365.common.util.BeanUtil;
import com.sd365.permission.centre.dao.mapper.DepartmentMapper;
import com.sd365.permission.centre.entity.Department;
import com.sd365.permission.centre.pojo.dto.CompanyDTO;
import com.sd365.permission.centre.pojo.dto.DepartmentDTO;
import com.sd365.permission.centre.pojo.query.DepartmentQuery;
import com.sd365.permission.centre.pojo.query.IdVersionQuery;
import com.sd365.permission.centre.service.DepartmentService;
import com.sd365.permission.centre.service.exception.BusinessErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @Author jxd
 * @Date 2020/12/12  1:01 下午
 * @Version 1.0
 * @Write For OrganizationServiceImpl
 * @Email waniiu@126.com
 */
@Slf4j
@Service
public class DepartmentServiceImpl extends AbstractBaseDataServiceImpl implements DepartmentService {

    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private IdGenerator idGenerator;

    @Resource
    DepartmentService departmentService;

    @Override
    public List<Department> commonQueryDepartment(DepartmentQuery departmentQuery) {
        try {
            List<Department> departments = departmentMapper.commonQueryDepartment(departmentQuery);
            Page page = (Page) departments;
            BaseContextHolder.set("pageInfo", JSON.toJSONString(new MyPageInfo(page.getTotal(), page.getPages())));
            return departments;
        } catch (Exception e) {
            throw new BusinessException(BusinessErrorCode.BUSINESS_COMPANY_COMMONQUERY_EXCEPTION_CODE, e);
        }

    }

    @Override
    public Boolean add(@Valid DepartmentDTO departmentDTO) {
        Department department = BeanUtil.copy(departmentDTO, Department.class);
        department.setId(idGenerator.snowflakeId());
        super.baseDataStuff4Add(department);

        log.info("name:" + departmentDTO.getCreator());
        //获取到创建者信息，进而获取公司，机构，租户id
        /**
         * 1、通过name，在用户表查询用户信息
         * 2、获取用户公司，机构，租户id
         * 3、设置department对应值
         */
        department.setVersion(0L);
        department.setStatus(Byte.parseByte("1"));

        // 判断 authCompanyId 是否为空 若不为空则将 companyId 取为这个字段
        // 否则使用当前用户的 companyId
        Long companyId = Optional.ofNullable(departmentDTO.getAuthCompanyId()).orElse(departmentDTO.getCompanyId());
        department.setCompanyId(companyId);

        return departmentMapper.insert(department) > 0;
    }

    @Override
    public Boolean remove(Long id, Long version) {
        Example example = new Example(Department.class);
        example.createCriteria().andEqualTo("id", id).andEqualTo("version", version);
        return departmentMapper.deleteByExample(example) > 0;
    }

    @Override
    public Boolean modify(DepartmentDTO departmentDTO) {
        Department department = BeanUtil.copy(departmentDTO, Department.class);
        super.baseDataStuff4Updated(department);

        // 判断 authCompanyId 是否为空 若不为空则将 companyId 取为这个字段
        // 否则使用当前用户的 companyId
        Long companyId = Optional.ofNullable(departmentDTO.getAuthCompanyId()).orElse(departmentDTO.getCompanyId());
        department.setCompanyId(companyId);

        Example example = new Example(Department.class);
        example.createCriteria().andEqualTo("id", departmentDTO.getId()).andEqualTo("version", departmentDTO.getVersion());

        return departmentMapper.updateByExample(department, example) > 0;
    }

    /**
     * 单行起停用操作
     *
     * @param departmentDTO
     * @return
     * @author Yan Huazhi
     * @date 2020/12/18 9:47
     * @version 0.0.1
     */
    @Override
    public Boolean batchModify(DepartmentDTO departmentDTO) {
        departmentDTO.setUpdatedTime(new Date());
        Department department = BeanUtil.copy(departmentDTO, Department.class);
        super.baseDataStuff4Updated(department);
        Example example = new Example(Department.class);
        example.createCriteria().andEqualTo("id", departmentDTO.getId()).andEqualTo("version", departmentDTO.getVersion());
        return departmentMapper.updateByExampleSelective(department, example) > 0;
    }

    @Override
    public List<DepartmentDTO> commonQuery(DepartmentQuery departmentQuery) {
        try {
            if (departmentQuery == null) {
                throw new BusinessException(com.sd365.common.core.common.exception.code.BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID, new Exception("commonQuery 方法错误"));
            }
            //先根据部门名称查询

            List<Department> departments = departmentMapper.commonQueryDepartment(departmentQuery);
            Page page = (Page) departments;
            BaseContextHolder.set("pageInfo", JSON.toJSONString(new MyPageInfo(page.getTotal(), page.getPages())));
            List<DepartmentDTO> departmentDTOS = BeanUtil.copyList(departments, DepartmentDTO.class);


            return departmentDTOS;

        } catch (BeanException ex) {
            throw new BusinessException(com.sd365.common.core.common.exception.code.BusinessErrorCode.SYSTEM_BEAN_COPY_EXCEPTION, ex);
        }
    }

    @Override
    public DepartmentDTO queryById(Long id) {
        try {
            DepartmentDTO departmentDTO = null;
            Department department = departmentMapper.selectByPrimaryKey(id);
            if (department != null) {
                departmentDTO = BeanUtil.copy(department, DepartmentDTO.class);
            }
            return departmentDTO;
        } catch (BeanException ex) {
            throw new BusinessException(com.sd365.common.core.common.exception.code.BusinessErrorCode.SYSTEM_BEAN_COPY_EXCEPTION, ex);
        }
    }

    @Override
    public DepartmentDTO copy(Long id) {
        if (null == id) {
            return new DepartmentDTO();
//            throw new RuntimeException("传输参数为空异常:copy方法");
        }
        Department department = departmentMapper.selectByPrimaryKey(id);
        if (department != null) {
            return BeanUtil.copy(department, DepartmentDTO.class);
        } else return new DepartmentDTO();
    }

    @Override
    public Boolean deleteBatch(List<IdVersionQuery> batchQuery) {
        boolean flag = true;
        for (IdVersionQuery query : batchQuery) {
            try {
                if (!departmentService.remove(query.getId(), query.getVersion())) {
                    log.info("id: " + query.getId() + "version: " + query.getVersion() + "删除失败");
                    flag = false;
                }
            } catch (Exception e) {
                throw new BusinessException(BusinessErrorCode.BUSINESS_PC_MONITOR_STATE_DB_EXCEPTION_CODE, e);
            }
        }
        return flag;
    }

    @Override
    public List<DepartmentDTO> builderTree(DepartmentQuery departmentQuery) {
        List<Department> departments = departmentMapper.commonQueryDepartment(departmentQuery);
        List<DepartmentDTO> departmentDTOS = BeanUtil.copyList(departments, DepartmentDTO.class, new BeanUtil.CopyCallback() {
            @Override
            public void copy(Object o, Object o1) {
                Department department = (Department) o;
                DepartmentDTO departmentDTO = (DepartmentDTO) o1;
                if (department.getCompany() != null) {
                    CompanyDTO copy = BeanUtil.copy(department.getCompany(), CompanyDTO.class);
                    departmentDTO.setCompanyDTO(copy);
                }
            }
        });

        if (!CollectionUtils.isEmpty(departmentDTOS)) {
            List<DepartmentDTO> tree = new ArrayList<>();
            for (DepartmentDTO departmentDTO : departmentDTOS) {
                if (departmentDTO.getParentId().compareTo(-1L) == 0) {
                    tree.add(departmentDTO);
                }
            }
            for (DepartmentDTO departmentDTO : tree) {
                builderNode(departmentDTOS, departmentDTO);
            }
            return tree;
        } else return new ArrayList<>();
    }

    @Override
    public void builderNode(List<DepartmentDTO> list, DepartmentDTO departmentDTO) {
        if (departmentDTO.getParentId() != null) {
            List<DepartmentDTO> departmentDTOS = new ArrayList<>();
            for (DepartmentDTO dto : list) {
                if (dto.getParentId().compareTo(departmentDTO.getId()) == 0) {
                    departmentDTOS.add(dto);
                }
            }
            departmentDTO.setDepartmentDTOS(departmentDTOS);
            if (!CollectionUtils.isEmpty(departmentDTOS)) {
                for (DepartmentDTO dto : departmentDTOS) {
                    builderNode(list, dto);
                }
            }
        }
    }
}
